/*
 * JOGRE (Java Online Gaming Real-time Engine) - Spades
 * Copyright (C) 2004  Bob Marks (marksie531@yahoo.com)
 * http://jogre.sourceforge.org
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.jogre.mayi.client;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.jogre.client.awt.JogreComponent;
import org.jogre.common.games.Card;
import org.jogre.common.games.Deck;
import org.jogre.mayi.server.MayIConstants;

/**
 * Component for making a bid for a spades hand
 *
 * @author Garrett Lehman (Gman)
 * @version Alpha 0.2.3
 */
public class MayIPlayerHandComponent extends JogreComponent {
	
	private boolean myHand = true;

	// Card pressed
	private Card cardPressed = null;

	// Card clicked
	private List<Card> cardsClicked = new ArrayList<Card>();
	
	private List<Card> cards = new ArrayList<Card>();

	/**
	 * Default constructor which takes a spades model
	 *
	 * @param spadesModel
	 *            Link to the main spades model
	 */
	public MayIPlayerHandComponent(boolean myHand) {
		
		int cardHeight = Card.CARD_PIXEL_HEIGHT;
		int cardWidth = Card.CARD_PIXEL_WIDTH;
		int cardSpacing = Card.CARD_SPACING;

		int width = cardWidth + (cardSpacing * 15);
		int height = cardHeight + cardSpacing;

		setPreferredSize(new Dimension(width, height));
		repaint();
		
		this.myHand = myHand;
	}

	/**
	 * Refresh the component.
	 *
	 * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
	 */
	public void paintComponent(Graphics g) {
		// draw background
		drawBackground(g);

		// draw cards on table
		drawCards(g);
	}

	/**
	 * Draw background
	 *
	 * @param g
	 *            Graphics
	 */
	public void drawBackground(Graphics g) {
		g.setColor(Color.WHITE);
		g.fillRect(0, 0, getWidth(), getHeight());
	}

	public synchronized void drawCards(Graphics g) {
		int i = 0;
		for (Card c : cards) {
			int x = i * Card.CARD_SPACING;
			int y = Card.CARD_SPACING;

			for (Card cc : this.cardsClicked) {
				if (cc == c) {
					y -= Card.CARD_SPACING;
				}
			}

			c.paintComponent(g, x, y);
			i++;
		}
	}

	/**
	 * Get card index by mouse x and y coordinates
	 *
	 * @param mouseX
	 *            Mouse x coordinate
	 * @param mouseY
	 *            Mouse y coordinate
	 * @return the card index by mouse x and mouse y
	 */
	public synchronized Card getCard(int mouseX, int mouseY) {
		int width = this.getWidth();
		int height = this.getHeight();

		Point topLeftPoint = new Point(0, 0);
		Point bottomRightPoint = new Point(width, height);

		if (mouseX < topLeftPoint.x || mouseX > bottomRightPoint.x
				|| mouseY < topLeftPoint.y || mouseY > bottomRightPoint.y) {
			return null;
		}


		int x = 0;
		int y = 0;
		Point topLeftCardPoint = null;
		Point bottomRightCardPoint = null;
		for (int i = (this.cards.size()-1); i >= 0; i--) {
			Card card = this.cards.get(i);
			
			x = i * Card.CARD_SPACING;
			y = Card.CARD_SPACING;
			if (cardsClicked.contains(card)) {
				y = 0;
			}
			topLeftCardPoint = new Point(x, y);

			x += Card.CARD_PIXEL_WIDTH;
			y += Card.CARD_PIXEL_HEIGHT;
			bottomRightCardPoint = new Point(x, y);

			if (mouseX > topLeftCardPoint.x
					&& mouseX < bottomRightCardPoint.x
					&& mouseY > topLeftCardPoint.y
					&& mouseY < bottomRightCardPoint.y) {
				return card;
			}
		}
		return null;
	}


	public void press(int mouseX, int mouseY) {
		Card card = getCard(mouseX, mouseY);
		this.cardPressed = card;
	}
	
	public synchronized Card discard(Card c) {
		cards.remove(c);
		this.repaint();
		return c;
	}
	
	public synchronized void moveClicked() {
		for (Card c : cardsClicked) {
			cards.remove(c);
		}
		cardsClicked.clear();
		this.repaint();
	}
	
	public List<Card> getCardsClicked() {
		return cardsClicked;
	}
	
	public synchronized void initializeCards(Deck deck) {
		this.cards.clear();
		for (int i = 0; i < deck.size(); i++) {
			Card c = deck.get(i);
			if (this.myHand) {
				c.setFaceUp(true);
			}
			cards.add(c);
		}
		this.repaint();
	}
	
	public synchronized void click(int mouseX, int mouseY) {
		Card card = getCard(mouseX, mouseY);
		if (card != null && this.cardPressed.equals(card)) {
			if (cardsClicked.contains(card)) {
				cardsClicked.remove(card);
			}
			else {
				cardsClicked.add(card);
			}
			this.repaint();
		}
	}
	
	public synchronized void addCard(Card c) {
		if (this.myHand) {
			c.setFaceUp(true);
		}
		else {
			c.setFaceUp(false);
		}
		this.cards.add(c);
		Collections.sort(this.cards, new CardComparator());
		this.repaint();
	}
	
	public boolean isOut() {
		return this.cards.isEmpty();
	}
	
	public synchronized int getPoints() {
		int points = 0;
		for (Card c : this.cards) {
			points += MayIConstants.getPoints(c);
		}
		return points;
	}
	
	public synchronized void reset() {
		this.cards.clear();
		this.cardsClicked.clear();
		this.cardPressed = null;
		
		this.repaint();
	}
}